using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Collections;
using XYThreadPoolLib;
using System.Diagnostics;
using Magnolia;

namespace CommLayer
{
    class TcpIpServerMedialon : TcpIpServer
    {
        byte m_prefix;
        byte m_suffix;

        /// <summary>
        /// Constructor. Sets suffix, prefix, and no ping 
        /// </summary>
        /// <param name="sAddress"></param>
        /// <param name="nPort"></param>
        /// <param name="nMinThreadCount"></param>
        /// <param name="nMaxThreadCount"></param>
        /// <param name="prefix"></param>
        /// <param name="suffix"></param>
        public TcpIpServerMedialon(string sAddress, int nPort, int nMinThreadCount, int nMaxThreadCount, byte prefix, byte suffix,
            ConnectionFilterDelegate delegateConnectionFilter,StringInputHandlerDelegate delegateStringInputHandler,ExceptionHandlerDelegate delegateExceptionHandler)
            :
            base(sAddress, nPort, nMinThreadCount, nMaxThreadCount, 
            delegateConnectionFilter, delegateStringInputHandler, delegateExceptionHandler)
        {
            m_prefix = prefix;
            m_suffix = suffix;
            Ping = false;

        }



        /// <summary>
        /// Send string data to everyone conencted
        /// </summary>
        /// <param name="sRemoteAddress"></param>
        /// <param name="nRemotePort"></param>
        /// <param name="sData"></param>
        /// <returns></returns>
        public override bool SendStringData(String sData)
        {
            bool bRet = true;
            try
            {
                if (m_htTransmissions.Count == 0)
                {
                    //throw new Exception("no active connections");
                }
                
                // construct the data
                Byte[] pData = new Byte[sData.Length + 2];
                pData[0] = m_prefix;
                pData[sData.Length + 1] = m_suffix;
                Byte[] bytes = System.Text.Encoding.ASCII.GetBytes(sData);
                bytes.CopyTo(pData, 1);

                // get the address of the sender (get the first client that was connected)
                foreach (DictionaryEntry di in m_htTransmissions)
                {
                    Trace.WriteLineIf(AppContext.AppTraceSwitch.TraceInfo, XYNetCommon.GetTimeString() + "SendStringData: " + sData);
                
                    Transmission trn = (Transmission)(di.Value);
                    Socket sock = trn.m_socket;
                    IPEndPoint ipe = (IPEndPoint)(sock.RemoteEndPoint);

                    bool bRetLocal = SendRawData(ipe.Address.ToString(), ipe.Port, pData);
                    bRet = bRetLocal && bRet;
                    // do not proceed on error because this might have changed m_htTransmissions
                    if (!bRet)
                        break;
                }
            }
            catch (Exception oBug)
            {
                // trace from here so we can send the line number one day
                Trace.WriteLineIf(AppContext.AppTraceSwitch.TraceError, "exception in SendStringData(" + sData + "):" + oBug.Message);

                // and handle exception regularly
                HandleException(oBug, null);

                return false;
            }
            return bRet;
        }

        /// <summary>
        /// readd transmission to list
        /// </summary>
        public void ReaddTransmission(Transmission trn)
        {
             Monitor.Enter(this);
            m_listTransmissions.Add(trn);
            Monitor.Exit(this);
        }




    }
}
